﻿using System;
using System.Collections.Generic;
using System.Text;
using WsProtocol.IEC62056.DataTypeClass;
using Comm.PublicClass;
using Comm.MultiLan;

namespace WsProtocol.IEC62056.CosemACSE 
{
    //实现设置服务原语的所有类

    //初步代码处理完成
    public class SetNormal
    {        
        public static string Request(CosemObject OI, ref string errorinfo)
        {
            string FormatValue = string.Empty;
            try
            {
                FormatValue = ADWithSel.GetFormatValue(OI, ref errorinfo);

                if (OI.DataNode == null) return FormatValue;

                FormatValue += Data.GetFormatValue(OI.DataNode, ref errorinfo);
            }
            catch (Exception ex)
            {
                errorinfo = ex.ToString();
            }
            return FormatValue;
        }

        public static int Response(ref string frameData, CosemObject OI, ref string errorinfo)
        {
            int iResult = 0;
            if (string.IsNullOrEmpty(frameData))
            {
                return iResult;
            }
            try
            {                
                string resultflag = frameData.Substring(0, 2);

                frameData = frameData.Remove(0, 2);//去掉结果字节

                if (Convert.ToInt32(resultflag, 16) ==(int)DAR.成功)
                {
                    iResult = 0;
                    OI.result = "0";
                    errorinfo = "";
                }
                else
                {
                    iResult = 0;                  
                    string resultStr =clsLan.GetLan(((DAR)Convert.ToInt32(resultflag, 16)).ToString());//解析错误信息 
                    OI.result = MyConvert.HexToDec(resultflag) + ":" + resultStr;
                    if (resultStr == null)
                        OI.result += clsLan.GetLan("协议中未规定此错误号对应的错误信息") ; 
                }               

            }    
            catch (Exception ex)
            {
                errorinfo = ex.ToString();
                iResult = -1;
            }
            return iResult;
        }

    }
    //初步代码处理完成
    public class SetFirstOrLastDatablock
    {
        public static string Request(CosemObject OI, ref string errorinfo)
        {
            string FormatValue = string.Empty;
            try
            {               
                FormatValue = ADWithSel.GetFormatValue(OI,ref errorinfo);                
                
                FormatValue += DataBlockSA.GetFormatValue(OI.DataNode,ref errorinfo);               
               
            }
            catch (Exception ex)
            {
                errorinfo = ex.ToString();
            }
            return FormatValue;
        }

        public static string Request(CosemObject OI,ref string BlockData, int DataLen,ref string errorinfo)
        {
            string FormatValue = string.Empty;
            try
            {
                FormatValue = ADWithSel.GetFormatValue(OI, ref errorinfo);
                //string slen = BERiLen.GetFormatValue(DataLen - FormatValue.Length);
                //string mblockData = BlockData.Substring(0, DataLen * 2 - FormatValue.Length - slen.Length-10);
                int SDataLen = DataLen - FormatValue.Length;
                FormatValue += DataBlockSA.GetFormatValue(BlockData, ref SDataLen,1,ref errorinfo);
                BlockData = BlockData.Substring(SDataLen);

            }
            catch (Exception ex)
            {
                errorinfo = ex.ToString();
            }
            return FormatValue;
        }

        public static int Response(ref string frameData, CosemObject OI, ref long frameseq, ref string errorinfo)
        {
            int iResult = -1;
            if (string.IsNullOrEmpty(frameData))
            {
                errorinfo = clsLan.GetLan("解析数据为空");
                return iResult;
            }
            try
            {
                iResult = SetNormal.Response(ref frameData, OI, ref errorinfo);
                //解析出块序号
                if (iResult >= 0)
                {
                    ElementData eleNode = new ElementData();
                    iResult = doublelongunsigned.AnalizeData(ref frameData, eleNode, ref  errorinfo);
                    frameseq = Convert.ToInt64(eleNode.ReadValue);
                }
            }
            catch (Exception ex)
            {
                errorinfo = ex.ToString();
                iResult = -1;
            }
            return iResult;
        }


    }
    //初步代码处理完成
    public class SetDatablock{
    
        public static string Request(CosemObject OI, ref string errorinfo)
        {
           
            return DataBlockSA.GetFormatValue(OI.DataNode,ref errorinfo);
        }

        public static string Request(ref string FrameValue, int DataLen, double frameseq, ref string errorinfo)
        {
           // int mDatalen = finished ? FrameValue.Length / 2 : DataLen;
           // string mblockData = FrameValue.Substring(0, mDatalen);
            int mDatalen = DataLen;
            string mblockData = DataBlockSA.GetFormatValue(FrameValue, ref mDatalen, frameseq,  ref errorinfo);
            FrameValue = FrameValue.Substring(mDatalen);
            return mblockData;
        }

        public static int Response(ref string frameData, CosemObject OI, ref long frameseq, ref string errorinfo)
        {
            int iResult = -1;
            if (string.IsNullOrEmpty(frameData))
            {
                errorinfo = clsLan.GetLan("解析数据为空");
                return iResult;
            }
            //解析出块序号
            try
            {
                ElementData eleNode = new ElementData();
                iResult = doublelongunsigned.AnalizeData(ref frameData, eleNode, ref  errorinfo);
                frameseq = Convert.ToInt64(eleNode.ReadValue);
            }
            catch (Exception ex) {
                errorinfo = ex.ToString();
                iResult = -1;
            }
            return iResult;
        }
    }
    
    //初步代码处理完成
    public class SetList : SetNormal
    {
        public static string Request(List<CosemObject> OIList,  ref string errorinfo)
        {
            string FormatValue = string.Empty;

            int eleNum = OIList.Count;
            string sData = string.Empty;
            foreach (CosemObject OI in OIList)
            {
                FormatValue = FormatValue + ADWithSel.GetFormatValue(OI,ref errorinfo);
                sData += Data.GetFormatValue(OI.DataNode,ref errorinfo);
            }

            return BERiLen.GetFormatValue(eleNum) + FormatValue + BERiLen.GetFormatValue(eleNum) + sData;
        }

        public static int Response(ref string frameData, List<CosemObject> OIList, ref string errorinfo)
        {
            int iResult = -1;
            if (string.IsNullOrEmpty(frameData))
            {
                errorinfo = clsLan.GetLan("解析数据为空");
                return iResult;
            }
            try
            {               
                int eleNum = BERiLen.AnalizeData(ref frameData, ref errorinfo);
                if (eleNum < 0)
                {
                    return -1;
                }
                for (int i = 0; i < eleNum; i++)
                {                    
                    if (i >= OIList.Count)
                    {
                        CosemObject OI = (CosemObject)OIList[OIList.Count - 1].DeepClone();
                        OIList.Add(OI);
                    }                    
                    iResult = SetNormal.Response(ref frameData, OIList[i], ref errorinfo);
                    if (iResult < 0) break;
                }
            }
            catch (Exception ex)
            {
                errorinfo = ex.ToString();
                iResult = -1;
            }
            return iResult;
        }
    }
    //初步代码处理完成
    public class SetListFirstOrLastDatablock : SetFirstOrLastDatablock
    {
        public static string Request(List<CosemObject> OIList,ref string BlockData,int DataLen, ref string errorinfo)
        {
            string FormatValue = string.Empty;
            try
            {
                foreach (CosemObject OI in OIList)
                {
                    FormatValue += ADWithSel.GetFormatValue(OI,ref errorinfo);
                }
                FormatValue = BERiLen.GetFormatValue(OIList.Count) + FormatValue;

                int SDataLen = DataLen - FormatValue.Length;
                FormatValue += DataBlockSA.GetFormatValue(BlockData, ref SDataLen,1, ref errorinfo);
                BlockData = BlockData.Substring(SDataLen);

                //string mblockData = BlockData.Substring(0, DataLen * 2 - FormatValue.Length - 10);

                //FormatValue += DataBlockSA.GetFormatValue(mblockData, 1, false, ref errorinfo);
                //BlockData = BlockData.Substring(mblockData.Length);

                               
            }
            catch (Exception ex)
            {
                errorinfo = ex.ToString();               
            }
            return FormatValue;
        }

        public static int Response(ref string frameData, List<CosemObject> OIList, ref long frameseq, ref string errorinfo)
        {
        
            int iResult = -1;
            if (string.IsNullOrEmpty(frameData))
            {
                errorinfo = clsLan.GetLan("解析数据为空");
                return iResult;
            }
            try
            {
                iResult = SetList.Response(ref frameData, OIList, ref errorinfo);
                //解析出块序号
                if (iResult >= 0)
                {
                    ElementData eleNode = new ElementData();
                    iResult = doublelongunsigned.AnalizeData(ref frameData, eleNode, ref  errorinfo);
                    frameseq = Convert.ToInt64(eleNode.ReadValue);
                }
            }
            catch (Exception ex)
            {
                errorinfo = ex.ToString();
                iResult = -1;
            }
            return iResult;
        }

    }
     
     
    public class ACSE_Set
    {
       // static string m_piid = "81";   //服务序号-优先级     PIID
        

        public static string Request(List<CosemObject> OIList,  string rwtype,int ApduSize, ref string errorinfo)
        {
            string FormatValue = string.Empty;

            SetRRMode setMode = (SetRRMode)Enum.Parse(typeof(SetRRMode), rwtype);
            string setTag = MyConvert.DecToHex(((int)ClientApduSel.SETRequest).ToString(), 2);
            switch (setMode)
            {
                case SetRRMode.SetNormal:
                    FormatValue = SetNormal.Request(OIList[0],  ref errorinfo);
                    break;                   
                case SetRRMode.SetList:
                    FormatValue = SetList.Request(OIList, ref errorinfo);
                    break;                   
                case SetRRMode.SetDatablock:
                    FormatValue = SetDatablock.Request(OIList[0], ref errorinfo);
                    break;
                case SetRRMode.SetFirstDatablock:
                    FormatValue = SetFirstOrLastDatablock.Request(OIList[0], ref errorinfo);
                    break;
                case SetRRMode.SetListFirstDatablock:
                    FormatValue = SetListFirstOrLastDatablock.Request(OIList[0], ref errorinfo);
                    break;

            }
            return  FormatValue;//MyConvert.DecToHex(((int)ClientApduSel.SETRequest).ToString(), 2) + MyConvert.DecToHex(((int)setMode).ToString(), 2) + m_piid +
        }

        public static int Response(ref string frameData, List<CosemObject> OIList, ref long frameseq, ref string errorinfo)
        {
            int iResult = 0;
            try
            {
                if (string.IsNullOrEmpty(frameData))
                {
                    errorinfo = clsLan.GetLan("解析数据为空");
                    return -1;
                }
                string tmp = frameData.Substring(0, 2);
                SetREMode getMode = (SetREMode)Enum.Parse(typeof(SetREMode), frameData.Substring(0, 2));
                string piid = frameData.Substring(2, 2);

                frameData = frameData.Substring(4); //去掉前面的回应类标志、PIID

                switch (getMode)
                {
                    case SetREMode.SetNormal:
                        //只一个OAD
                        iResult = SetNormal.Response(ref frameData, OIList[0],  ref  errorinfo);
                        break;
                    case SetREMode.SetList:
                        //包含多个OAD
                        iResult = SetList.Response(ref frameData, OIList, ref  errorinfo);
                        break;
                    case SetREMode.SetDatablock:
                        iResult = SetDatablock.Response(ref frameData, OIList[0],ref  frameseq, ref  errorinfo);
                        break;
                    case SetREMode.SetLastDatablock:
                        iResult = SetFirstOrLastDatablock.Response(ref frameData, OIList[0],ref  frameseq, ref  errorinfo);
                        break;
                    case SetREMode.SetLastDatablockList:
                        iResult = SetListFirstOrLastDatablock.Response(ref frameData, OIList[0], ref  frameseq,ref  errorinfo);
                        break;
                }

            }
            catch (Exception ex)
            {
                errorinfo = ex.ToString();
                iResult = -1;
            }
            return iResult;

        }
    }

  
}
